package com.wuyan.web.base.api;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.querydsl.core.types.Order;
import com.querydsl.core.types.OrderSpecifier;
import com.querydsl.core.types.Predicate;
import com.querydsl.core.types.dsl.PathBuilder;
import com.wuyan.web.base.aop.ApiLogAnnotation;
import com.wuyan.web.base.helper.rep.RepBody;
import com.wuyan.web.base.helper.rep.RepHelper;
import com.wuyan.web.base.helper.rep.RepPageData;
import com.wuyan.web.base.helper.rep.RepCodeEnum;
import com.wuyan.web.base.helper.req.CustomQueryHelper;
import com.wuyan.web.base.helper.req.CustomQueryParams;
import com.wuyan.web.base.helper.req.CustomQueryOrderParams;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import com.wuyan.web.base.entity.PubArticleContent;
import com.wuyan.web.base.entity.QPubArticleContent;
import com.wuyan.web.base.form.PubArticleContentForm;
import com.wuyan.web.base.service.PubArticleContentService;
import lombok.extern.slf4j.Slf4j;


import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * controller for PubArticleContent generated by jpa-codegen
 * TODO
 * 接口遵循restful规范，其中post用于新增，get用于查询数据，put用于修改，delete用于删除，默认增加分页查询接口
 *
 * @author wuyan
 * @date 2021-06-07 18:41:06
 */

@Slf4j
@RestController
@RequestMapping("/api/pub-article-content")
public class PubArticleContentApi implements RepHelper {

    @Autowired
    private PubArticleContentService pubArticleContentService;

    @PostMapping
    @ApiLogAnnotation(name = "PubArticleContent:create")
    public RepBody<PubArticleContent> create(@RequestBody @Validated PubArticleContentForm form) throws Exception {
        PubArticleContent pubArticleContent = pubArticleContentService.create(form);
        return ok(pubArticleContent);
    }

    @PostMapping("/plist")
    @ApiLogAnnotation(name = "PubArticleContent:creates")
    public RepBody<List<PubArticleContent>> creates(@RequestBody @Validated List<PubArticleContentForm> forms) throws Exception {
        List<PubArticleContent> res = pubArticleContentService.creates(forms);
        return ok(res);
    }

    @DeleteMapping("/{id}")
    @ApiLogAnnotation(name = "PubArticleContent:delete")
    public RepBody<Integer> delete(@PathVariable("id") Integer[] id) {
        return ok(pubArticleContentService.delete(id));
    }

    @PutMapping("/{id}")
    @ApiLogAnnotation(name = "PubArticleContent:update")
    public RepBody<PubArticleContent> update(@RequestBody @Validated PubArticleContentForm form,
                                    @PathVariable("id") Integer id) throws Exception {
        Optional<PubArticleContent> pubArticleContent = pubArticleContentService.update(form, id);
        return pubArticleContent.isPresent() ? ok(pubArticleContent.get()) : error(RepCodeEnum.ERR_NO_ID);
    }

    /**
    * 根据ID更新指定字段的值
    *
    * @param id    id
    * @param field 字段名
    * @param value 值
    * @return RepBody<Object>
    */
    @PutMapping("/{id}/{field}/{value}")
    @ApiLogAnnotation(name = "PubArticleContent:updateByField")
    public RepBody<Long> updateByField(@PathVariable("id") Integer id,
                                        @PathVariable("field") String field,
                                        @PathVariable("value") String value) throws Exception {
        long update = pubArticleContentService.updateByField(id, field, value);
        return update > 0 ? ok(update) : error(RepCodeEnum.ERR_UPDATE);
    }

    @GetMapping("/{id}")
    @ApiLogAnnotation(name = "PubArticleContent:get")
    public RepBody<PubArticleContent> get(@PathVariable("id") Integer id) {
        Optional<PubArticleContent> pubArticleContent = pubArticleContentService.get(id);
        return pubArticleContent.isPresent() ? ok(pubArticleContent.get()) : error(RepCodeEnum.ERR_NO_ID);
    }

    /**
    *
    * @param isPage 是否分页
    * @param page 当前页
    * @param limit 条目数
    * @param params 查询参数：数组形式JSON字符串
    * @param ordersParams 排序参数：数组形式JSON字符串
    * @return RepBody<RepPageData<PubArticleContent>>
    */
    @SneakyThrows
    @GetMapping
    @ApiLogAnnotation(name = "PubArticleContent:page")
    public RepBody<RepPageData<PubArticleContent>> page(@RequestParam(value = "isPage", required = false, defaultValue = "true") Boolean isPage,
                                                          @RequestParam(value = "page", required = false, defaultValue = "1") Integer page,
                                                          @RequestParam(value = "limit", required = false, defaultValue = "15") Integer limit,
                                                          @RequestParam(value = "params", required = false, defaultValue = "[]") String params,
                                                          @RequestParam(value = "orders", required = false, defaultValue = "[]") String ordersParams) {

        ObjectMapper mapper = new ObjectMapper();
        // 查询参数
        List<CustomQueryParams> paramsList = mapper.readValue(params, new TypeReference<List<CustomQueryParams>>() {});
        // 排序参数
        List<CustomQueryOrderParams> orderList = mapper.readValue(ordersParams, new TypeReference<List<CustomQueryOrderParams>>() {});

        QPubArticleContent q = QPubArticleContent.pubArticleContent;
        PathBuilder<PubArticleContent> pathBuilder = new PathBuilder<>(PubArticleContent.class, q.getMetadata());

        // 默认排序
        if(null == orderList || orderList.isEmpty()){
            orderList = new ArrayList<>();
        }

        // 构建查询条件
        CustomQueryHelper<PubArticleContent> customQueryHelper = CustomQueryHelper.<PubArticleContent>builder()
                    .paramsList(paramsList)
                    .pathBuilder(pathBuilder)
                    .paramsOrders(orderList)
                    .entityClass(PubArticleContent.class)
                    .build()
                    .structure();

        List<Predicate> predicates = customQueryHelper.getPredicates();
        List<OrderSpecifier<?>> orders = customQueryHelper.getOrders();

        // TODO 业务逻辑
        // TODO 业务逻辑

        return ok(pubArticleContentService.page(predicates, orders, isPage, page, limit));
    }

}